package com.probox.common.entity.service.customer.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.probox.common.core.constant.CachePrefix;
import com.probox.common.core.constant.Constants;
import com.probox.common.core.enums.*;
import com.probox.common.core.utils.SecurityUtils;
import com.probox.common.entity.domain.customer.CustomerFund;
import com.probox.common.entity.domain.customer.CustomerFundDetail;
import com.probox.common.entity.domain.customer.CustomerFundStore;
import com.probox.common.entity.domain.customer.CustomerLevelInfo;
import com.probox.common.entity.domain.platfom.PlatformInfo;
import com.probox.common.entity.mapper.customer.CustomerFundDetailMapper;
import com.probox.common.entity.mapper.customer.CustomerFundMapper;
import com.probox.common.entity.mapper.customer.CustomerLevelInfoMapper;
import com.probox.common.entity.mapper.customer.CustomerLevelMapper;
import com.probox.common.entity.service.centre.ICustomerInfoService;
import com.probox.common.entity.service.customer.*;
import com.probox.common.entity.service.platfom.IPlatformInfoService;
import com.probox.common.entity.vo.customerService.CustomerServiceBuyRecordVo;
import com.probox.common.redis.service.RedisService;
import com.probox.customer.api.domain.CustomerFundVo;
import com.probox.customer.api.domain.CustomerLevel;
import com.probox.order.api.domain.OrderQuery;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * 客户收益Service业务层处理
 *
 * @author zsy
 * @date 2021-06-18
 */
@Service
@Transactional
public class CustomerFundServiceImpl extends ServiceImpl<CustomerFundMapper, CustomerFund> implements ICustomerFundService {
    @Autowired
    private CustomerFundMapper customerFundMapper;

    @Autowired
    private CustomerFundDetailMapper customerFundDetailMapper;

    @Autowired
    private ICustomerFundDetailService customerFundDetailService;

    @Autowired
    private ICustomerLevelInfoService customerLevelInfoService;

    @Autowired
    private CustomerLevelInfoMapper customerLevelInfoMapper;

    @Autowired
    private CustomerLevelMapper customerLevelMapper;

    @Autowired
    private ICustomerFundHistoryService customerFundHistoryService;

    @Autowired
    private ICustomerFundStoreService fundStoreService;

    @Autowired
    private RedisService redisService;

    @Autowired
    private IPlatformInfoService platformInfoService;


    private static String customerInfoKey = CachePrefix.CUSTOMER_INFO_DETAIL;

    protected final Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 查询客户收益
     *
     * @param fundUid 客户收益ID
     * @return 客户收益
     */
    @Override
    public CustomerFund selectCustomerFundById(Long fundUid) {
        return this.getById(fundUid);
    }

    @Override
    public CustomerFund getByCustomerId(Long customerId) {
        QueryWrapper<CustomerFund> queryWrapper = Wrappers.query();
        queryWrapper.eq("CUSTOMER_UID", customerId);
        List<CustomerFund> list = customerFundMapper.selectList(queryWrapper);
        if (list.size() > 0) {


            CustomerFund customerFund = list.get(0);

            return customerFund;
        }
        return null;
    }

    /**
     * 确认抵扣
     * @param cfd
     */
    @Override
    public void confirmDeduction(CustomerFundDetail cfd) {
        cfd.setDataStatus(DataStatus.valid.getKey());
        cfd.setUpdateTime(new Date());
        if (customerFundDetailService.updateById(cfd)){
            CustomerFund cf = getByCustomerId(cfd.getCustomerUid());
            if (cf != null){
                if(cf.getFreezeRedBag() == null){
                    cf.setFreezeRedBag(0L);
                }
                if (cfd.getBizType().equals("score")){
                    cf.setScore(cf.getScore()+cfd.getAmount());
                    cf.setFreezeScore(cf.getFreezeScore()+cfd.getAmount());
                }else{
                    cf.setRedBag(cf.getRedBag()+cfd.getAmount());
                    cf.setFreezeRedBag(cf.getFreezeRedBag()+cfd.getAmount());
                }
                updateById(cf);
            }
        }
    }


    /**
     * 减少客户资金信息
     *
     * @param fund
     * @return
     */
    //@Transactional(propagation = Propagation.REQUIRES_NEW)
    @Override
    public int deductionCustomerFund(CustomerFundVo fund) {
        //新增客户资金历史记录
        QueryWrapper<CustomerFund> fundQueryWrapper = new QueryWrapper<>();
        fundQueryWrapper.eq("CUSTOMER_UID", fund.getCustomerUid());
        CustomerFund customerFund = customerFundMapper.selectOne(fundQueryWrapper);
        if (customerFund == null) {
            customerFund = new CustomerFund();
            customerFund.setCustomerUid(fund.getCustomerUid());
            customerFund.setAllFans(0);
            customerFund.setAllBalance(0L);
            customerFund.setAllFansSecond(0);
            customerFund.setAllProfit(0L);
            customerFund.setAllScore(0L);
            customerFund.setAllWithdraw(0l);
            customerFund.setAllRedBag(0L);
            customerFund.setFreezeScore(0L);
            customerFund.setBalance(0L);
            customerFund.setRedBag(0L);
            customerFund.setAllRedBag(0L);
            customerFund.setCreateTime(new Date());
            customerFund.setPlatformUid(Constants.DEFAULT_PLATFORM_ID);
            customerFund.setUpdateTime(new Date());
            customerFund.setScore(0L);
            customerFund.setProfit(0L);
            customerFund.setFreezeProfit(0L);
            this.save(customerFund);
        }
        //减少客户资金信息
        List<CustomerFundDetail> list = new ArrayList<>();
        if (fund.getCustomerUid() != null) {
            CustomerFund data = new CustomerFund();
            data.setCustomerUid(fund.getCustomerUid());
            if (fund.getScore() != null && fund.getScore() > 0) {
                data.setScore(fund.getScore());
                CustomerFundDetail detail = new CustomerFundDetail();
                detail.setCustomerUid(fund.getCustomerUid());
                detail.setCreateTime(new Date());
                detail.setBizDesc(fund.getBizDesc());
                detail.setBizType(CustomerFundBizTypeEnum.score.getKey());
                detail.setBizNo(fund.getBizNo());
                detail.setBizTime(fund.getBizTime());
                detail.setItemUid(fund.getItemUid());
                detail.setStoreId(fund.getStoreId());
                detail.setRemark(fund.getRemark());
                detail.setUpdateTime(detail.getCreateTime());
                detail.setAmount(0 - data.getScore());
                detail.setOrderUid(fund.getOrderUid());
                detail.setPlatformUid(fund.getPlatformUid());
                detail.setFromCustomerUid(fund.getFromCustomerId());
                detail.setDataStatus(fund.getStatus());
                detail.setFundStatus(CustomerFundHistoryTypeEnum.outflow.getKey());
                detail.setCreateUser(SecurityUtils.getUserId());
                detail.setCreateName(SecurityUtils.getUsername());
                list.add(detail);
            }

            //删除客户基本信息缓存
            redisService.deleteObject(customerInfoKey + customerFund.getCustomerUid());
            logger.info("成功删除客户id:{}的缓存信息", customerFund.getCustomerUid());
            if (list.size() > 0) {
                if (customerFundMapper.deductionCustomerFund(data) > 0) {
                    customerFundDetailService.saveBatch(list);
                    return 1;
                }
            }
        }
        return 0;
    }

    /**
     * 赠送积分
     * @param sendType
     * @param customerUid
     * @return
     */
    @Override
    public int sendJiFen(String sendType,Long customerUid){
        int rst =0;
        Integer jifen = 0;
        String jifeName = "";
        String remark = "";
        PlatformInfo info = platformInfoService.getById(SecurityUtils.getPlatformId());
        if (info != null){
            if (sendType.equalsIgnoreCase("register")){
                jifen = info.getRegisterJifen();
                jifeName = "注册赠送积分";
                remark = "新用户注册系统赠送积分";
            }else if (sendType.equalsIgnoreCase("invitation")){
                jifen = info.getInvitationJifen();
                jifeName = "邀请赠送积分";
                remark = "每邀请一个新用户注册可获得积分";
            }
            if (jifen != null && jifen>0){
                CustomerFundVo fund = new CustomerFundVo();
                fund.setCustomerUid(customerUid);
                fund.setBizDesc(jifeName);
                fund.setScore(jifen.longValue());
                fund.setStatus("1");
                fund.setBizTime(new Date());
                fund.setPlatformUid(1L);
                fund.setRemark(remark);
                addCustomerFund(fund);
                rst = 1;
            }
        }
        return rst;
    }

    @Override
    public Long countJiFen(OrderQuery query) {
        return customerFundMapper.countJiFen(query);
    }

    /**
     * 增加客户资金收益
     *
     * @param fund
     * @return
     */
    //@Transactional(propagation = Propagation.REQUIRES_NEW)
    @Override
    public int addCustomerFund(CustomerFundVo fund) {
        //新增客户资金历史记录
        QueryWrapper<CustomerFund> fundQueryWrapper = new QueryWrapper<>();
        fundQueryWrapper.eq("CUSTOMER_UID", fund.getCustomerUid());
        CustomerFund customerFund = customerFundMapper.selectOne(fundQueryWrapper);
        if (customerFund == null) {
            customerFund = new CustomerFund();
            customerFund.setCustomerUid(fund.getCustomerUid());
            customerFund.setAllFans(0);
            customerFund.setAllBalance(0L);
            customerFund.setAllFansSecond(0);
            customerFund.setAllProfit(0L);
            customerFund.setAllScore(0L);
            customerFund.setAllWithdraw(0l);
            customerFund.setAllRedBag(0L);
            customerFund.setFreezeScore(0L);
            customerFund.setBalance(0L);
            customerFund.setRedBag(0L);
            customerFund.setFreezeRedBag(0L);
            customerFund.setAllRedBag(0L);
            customerFund.setCreateTime(new Date());
            customerFund.setPlatformUid(Constants.DEFAULT_PLATFORM_ID);
            customerFund.setUpdateTime(new Date());
            customerFund.setScore(0L);
            customerFund.setProfit(0L);
            customerFund.setFreezeProfit(0L);
            this.save(customerFund);
        }

        //增加客户资金收益
        List<CustomerFundDetail> list = new ArrayList<>();
        CustomerFundDetail detail = null;
        CustomerFund data = new CustomerFund();
        data.setCustomerUid(fund.getCustomerUid());
        if (fund.getScore() != null && fund.getScore() > 0) {
            data.setScore(fund.getScore());
            detail = new CustomerFundDetail();
            detail.setCustomerUid(fund.getCustomerUid());
            detail.setCreateTime(new Date());
            detail.setBizDesc(fund.getBizDesc());
            detail.setBizType(CustomerFundBizTypeEnum.score.getKey());
            detail.setBizNo(fund.getBizNo());
            detail.setBizTime(fund.getBizTime());
            detail.setDataStatus(fund.getStatus());
            detail.setItemUid(fund.getItemUid());
            detail.setRemark(fund.getRemark());
            detail.setStoreId(fund.getStoreId());
            detail.setUpdateTime(detail.getCreateTime());
            detail.setAmount(data.getScore());
            detail.setOrderUid(fund.getOrderUid());
            detail.setPlatformUid(fund.getPlatformUid());
            detail.setFromCustomerUid(fund.getFromCustomerId());
            if (fund.getHisStatus() == null) {
                detail.setFundStatus(CustomerFundHistoryTypeEnum.flowInto.getKey());
            } else {
                detail.setFundStatus(fund.getHisStatus());
            }
            list.add(detail);
        }else if (fund.getRedBag() != null && fund.getRedBag() > 0) {
            data.setRedBag( fund.getRedBag());
            detail = new CustomerFundDetail();
            detail.setCustomerUid(fund.getCustomerUid());
            detail.setCreateTime(new Date());
            detail.setBizDesc(fund.getBizDesc());
            detail.setBizType(CustomerFundBizTypeEnum.paiban.getKey());
            detail.setBizNo(fund.getBizNo());
            detail.setBizTime(fund.getBizTime());
            detail.setDataStatus(fund.getStatus());
            detail.setItemUid(fund.getItemUid());
            detail.setRemark(fund.getRemark());
            detail.setStoreId(fund.getStoreId());
            detail.setUpdateTime(detail.getCreateTime());
            detail.setAmount(data.getRedBag());
            detail.setOrderUid(fund.getOrderUid());
            detail.setPlatformUid(fund.getPlatformUid());
            detail.setFromCustomerUid(fund.getFromCustomerId());
            if (fund.getHisStatus() == null) {
                detail.setFundStatus(CustomerFundHistoryTypeEnum.flowInto.getKey());
            } else {
                detail.setFundStatus(fund.getHisStatus());
            }
            list.add(detail);
        }

        //删除客户基本信息缓存
        redisService.deleteObject(customerInfoKey + fund.getCustomerUid());
        logger.info("成功删除客户id:{}的缓存信息", fund.getCustomerUid());
        //修改客户资金
        if (detail != null) {
            int count = 0;
            if (CustomerFundStatusEnum.valid.getKey().equals(fund.getStatus())) {
                count = customerFundMapper.addCustomerFund(data);
            } else if (CustomerFundStatusEnum.freeze.getKey().equals(fund.getStatus())) {
                count = customerFundMapper.freezeCustomerFund(data);
            }
            if (count > 0) {
                customerFundDetailService.saveBatch(list);
                return count;
            }
        }
        return 0;
    }

    /**
     * 查询客户收益列表
     *
     * @param customerFundvo 客户收益
     * @return 客户收益
     */
    @Override
    public List<com.probox.common.entity.vo.customer.CustomerFundVo> queryList(com.probox.common.entity.vo.customer.CustomerFundVo customerFundvo) {
        if (customerFundvo.getLevelUid() != null) {
//            CustomerLevel customerLevel = customerLevelMapper.selectById(customerFundvo.getLevelUid());
//            if ("1".equals(customerLevel.getCustomerPattern())) {
//                customerFundvo.setPayLevelUid(customerFundvo.getLevelUid());
//                customerFundvo.setLevelUid(null);
//            }
        }
        customerFundvo.setPlatformUid(SecurityUtils.getPlatformId());
        PageHelper.startPage(customerFundvo.getPageNum(), customerFundvo.getPageSize());
        List<com.probox.common.entity.vo.customer.CustomerFundVo> customerFundVoList = customerFundMapper.selectCustomerFund(customerFundvo);
        return customerFundVoList;
    }

    /**
     * 新增客户收益
     *
     * @param customerFund 客户收益
     * @return 结果
     */
    @Override
    public boolean insertCustomerFund(CustomerFund customerFund) {

        return this.save(customerFund);

    }

    @Override
    public String deductCustomerFund(CustomerFundVo fundVo) {
        String rst = "";
        CustomerFundVo vo = new CustomerFundVo();
        vo.setCustomerUid(fundVo.getCustomerUid());
        vo.setStoreId(fundVo.getStoreId());
        vo.setRemark(fundVo.getRemark());
        vo.setScore(fundVo.getScore());
        vo.setBalance(fundVo.getBalance());
        vo.setRedBag(fundVo.getRedBag());
        vo.setProfit(fundVo.getProfit());
        vo.setBizTime(new Date());
        CustomerFundStore storeFund = null;
        if (fundVo.getRedBag()>0 || fundVo.getBalance()>0){
            storeFund = fundStoreService.selectCustomerFund(fundVo.getStoreId(),fundVo.getCustomerUid());
            if (storeFund == null){
                rst = "没有找到该门店的资金信息";
                return rst;
            }
            if (storeFund.getBalance()<fundVo.getBalance()){
                rst = "该门店的金币余额不足";
                return rst;
            }
            if (storeFund.getRedBag()<fundVo.getRedBag()){
                rst = "该门店的银币余额不足";
                return rst;
            }
        }
        CustomerFund fund = this.getByCustomerId(fundVo.getCustomerUid());
        if (fund == null){
            rst = "没有找到客户资产记录";
            return rst;
        }
        if (fund.getProfit()<fundVo.getProfit()){
            rst = "经验不足，扣除失败";
            return rst;
        }
        if (fund.getScore()<fundVo.getScore()){
            rst = "菠萝派不足，扣除失败";
            return rst;
        }
        this.deductionCustomerFund(vo);
        if (storeFund != null){
            storeFund.setBalance(storeFund.getBalance()-fundVo.getBalance());
            storeFund.setAllBalance(storeFund.getAllBalance()-fundVo.getBalance());
            storeFund.setRedBag(storeFund.getRedBag()-fundVo.getRedBag());
            storeFund.setAllRedBag(storeFund.getAllRedBag()-fundVo.getRedBag());
            fundStoreService.updateById(storeFund);
        }
        if (fundVo.getProfit()>0){
            fund.setAllProfit(fund.getAllProfit()-fundVo.getProfit());
            if (fund != null) {
                //免费等级
                QueryWrapper<CustomerLevel> levelQueryWrapper = new QueryWrapper<>();
                levelQueryWrapper.le("MIN_SCORE", fund.getAllProfit());
                levelQueryWrapper.eq("DATA_STATUS", DataStatus.valid.getKey());
                levelQueryWrapper.eq("START_STATUS", CustomerLevelStartTypeEnum.start.getKey());
                //levelQueryWrapper.eq("CUSTOMER_PATTERN", CustomerLevelPatternTypeEnum.freeMode.getKey());
                levelQueryWrapper.orderByDesc("CUSTOMER_GRADE").last("limit 1");
                CustomerLevel customerLevel = customerLevelMapper.selectOne(levelQueryWrapper);
                //判断当前客户是否绑定等级
                QueryWrapper<CustomerLevelInfo> levelInfoQueryWrapper = new QueryWrapper<>();
                levelInfoQueryWrapper.eq("CUSTOMER_UID", fund.getCustomerUid());
                levelInfoQueryWrapper.eq("STATUS", DataStatus.valid.getKey());
                levelInfoQueryWrapper.last("order by LEVEL_INFO_ID desc limit 1");
                CustomerLevelInfo levelInfo = customerLevelInfoMapper.selectOne(levelInfoQueryWrapper);
                if (customerLevel != null) {
                    if (levelInfo == null || levelInfo.getLevelUid().longValue() != customerLevel.getLevelId()) {
                        levelInfo = new CustomerLevelInfo();
                        levelInfo.setLevelUid(customerLevel.getLevelId());
                        levelInfo.setCustomerUid(fund.getCustomerUid());
                        levelInfo.setStatus(DataStatus.valid.getKey());
                        levelInfo.setCustomeRgrade(customerLevel.getCustomerGrade().longValue());
                        levelInfo.setCreateTime(new Date());
                        levelInfo.setScore(fund.getAllProfit());
                        customerLevelInfoService.save(levelInfo);
                    }
                }
                redisService.deleteObject(customerInfoKey + fund.getCustomerUid());
            }
        }
        return rst;
    }

    /**
     * 修改客户收益
     *
     * @param customerFund 客户收益
     * @return 结果
     */
    @Override
    public boolean updateCustomerFund(CustomerFund customerFund) {

        return this.updateById(customerFund);
    }


    /**
     * 修改客户总资金
     * @param record
     */
    @Override
    public void updateFundByCardWithdrawal(CustomerServiceBuyRecordVo record){

    }

    /**
     * 批量删除客户收益
     *
     * @param fundUids 需要删除的客户收益ID
     * @return 结果
     */
    @Override
    public boolean deleteCustomerFundByIds(Long[] fundUids) {
        return this.removeByIds(Arrays.asList(fundUids));
    }

    //@Transactional(propagation = Propagation.REQUIRES_NEW)
    @Override
    public int setProfitInvalid(Long orderUid) {
        List<CustomerFundDetail> customerFundDetails = customerFundDetailMapper.selectAmountAndCustomerByOrderUid(orderUid);
        for (CustomerFundDetail fundDetail : customerFundDetails) {
            CustomerFund fund = new CustomerFund();
            fund.setProfit(fundDetail.getAmount());
            fund.setCustomerUid(fundDetail.getCustomerUid());
            customerFundMapper.setInvalidCustomerFund(fund);
        }
        logger.info("冻结资金解冻接受订单id:" + orderUid);
        UpdateWrapper<CustomerFundDetail> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("BIZ_TYPE", CustomerFundBizTypeEnum.profit.getKey());
        updateWrapper.eq("ORDER_UID", orderUid);
        updateWrapper.eq("DATA_STATUS", CustomerFundStatusEnum.freeze.getKey());
        updateWrapper.set("DATA_STATUS", CustomerFundStatusEnum.invalid.getKey());
        updateWrapper.set("UPDATE_TIME", DateUtil.date());
        customerFundDetailService.update(updateWrapper);
        return 0;
    }


}
